import { graphic, type EChartsOption } from "echarts";
import dayjs from "dayjs";
import { formatMissingData } from "@/utils/common";

const farmatLineData = (metaData: Record<string, any>, xAxisDataFormat: boolean = true): Record<string, any> => {
  const { name = "", unit = "", list = [] } = metaData;
  const title = unit ? `${name}（${unit}）` : name;
  const data = formatMissingData(list?.map(item => item?.num));
  const xAxisData = xAxisDataFormat ? list?.map(item => dayjs(item.name).format("MM/DD")) : list?.map(item => item.name);
  return { title, data, xAxisData };
};

/**
 * @description: 获取折线图series配置
 * @param {Record} seriesMetaData
 * @param {boolean} smooth 是否光滑曲线
 * @param {boolean} shadow 是否需要阴影
 * @param {boolean} markLineData 标注线数据
 * @return {*}
 */
const getEchartsLineSeries = (
  seriesMetaData: Record<string, any>,
  smooth: boolean = false,
  shadow: boolean = false,
  markLineData: Array<any> = []
): Array<Record<string, any>> => {
  const { title = "", data = [] } = seriesMetaData;
  const name = title;
  const type = "line";
  const symbol = "circle";
  const color = "#3B82F6";
  const itemStyle = { color };
  const lineStyle = {
    color,
    width: 1
  };
  const areaStyle = shadow
    ? {
        opacity: 0.4,
        color: new graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 1,
            color: "#74B4F9"
          },
          {
            offset: 0,
            color: "#407DF1"
          }
        ])
      }
    : undefined;
  const markLine = !!markLineData?.length
    ? {
        silent: true,
        symbol: ["none", "none"],
        lineStyle: {
          color: "#F45252"
        },
        // data: markLineData?.map(yAxis => ({ yAxis }))
        data: markLineData
      }
    : undefined;
  return [{ name, type, symbol, itemStyle, lineStyle, data: formatMissingData(data), smooth, areaStyle, markLine }];
};

/**
 * @description: 获取柱状图series配置
 * @param {Record} seriesMetaData

 * @return {*}
 */
const getEchartsBarSeries = (seriesMetaData: Record<string, any>, line: boolean = false): Array<Record<string, any>> => {
  const { title = "", data = [] } = seriesMetaData;
  const name = title;
  const type = "bar";
  const barWidth = 20;
  const itemStyle = {
    color: "#659AFF"
  };
  const lineStyle = {
    color: "#FECD4B",
    type: "dashed"
  };
  const itemStyleLine = {
    normal: {
      color: "#FECD4B"
    }
  };
  const smooth = true;
  const symbol = "circle";
  const symbolSize = 6;
  const tooltip = { show: false };
  const barSeries = { name, type, barWidth, itemStyle, data };
  const lineSeries = { name, type: "line", lineStyle, itemStyle: itemStyleLine, smooth, symbol, symbolSize, data, tooltip };
  return line ? [barSeries, lineSeries] : [barSeries];
};

/**
 * @description: 折线图
 * @param {Record} data
 * @param {boolean} xAxisDataFormat 是否需要处理xAxisData 默认需要
 * @param {boolean} smooth 是否光滑曲线
 * @param {boolean} shadow 是否需要阴影
 * @param {boolean} markLineData 标注线数据
 * @param {boolean} dark 是否暗黑模式
 * @param {function} cb
 * @return {*}
 */
export const useInitLineEcharts = (
  data: Record<string, any>,
  xAxisDataFormat: boolean = true,
  smooth: boolean = false,
  shadow: boolean = false,
  markLineData: Array<any> = [],
  dark: boolean = false,
  max: number | string = undefined,
  cb: (o: EChartsOption) => void
) => {
  const seriesMetaData = farmatLineData(data, xAxisDataFormat);
  const { xAxisData = [] } = seriesMetaData;
  const title = {
    text: `${data?.name}`,
    left: "center",
    textStyle: {
      fontSize: 12
    }
  };
  // const animation = false;
  const grid = {
    top: 50,
    bottom: -2,
    left: 12,
    right: !!markLineData?.length ? 60 : 16,
    containLabel: true
  };
  const tooltip = {
    trigger: "axis"
    // axisPointer: {
    //   type: "cross"
    // }
  };
  const xAxis = {
    type: "category",
    splitLine: {
      // show: true
    },
    boundaryGap: false,
    data: xAxisData
  };
  const yAxis = {
    // name: `${data?.name}${data?.unit ? "（" + data?.unit + "）" : ""}`,
    name: `${data?.unit || "--"}`,
    max,
    // nameLocation: "start",
    nameTextStyle: {
      align: "left",
      fontSize: 12
    },
    type: "value",
    splitLine: {
      show: true,
      lineStyle: {
        type: "dashed"
      }
    }
  };
  const series: Array<any> = [];
  const ac = getEchartsLineSeries(seriesMetaData, smooth, shadow, markLineData);
  series.push(...ac);
  cb && cb({ title, grid, tooltip, xAxis, yAxis, series } as EChartsOption);
};

/**
 * @description: 柱状图
 * @param {Record} data
 * @param {Record} line 是否需要辅助线
 * @param {function} cb
 * @return {*}
 */
export const useInitBarEcharts = (data: Record<string, any>, line: boolean = false, cb: (o: EChartsOption) => void) => {
  const seriesMetaData = farmatLineData(data);
  const { xAxisData = [] } = seriesMetaData;
  const title = {
    text: `${data?.name}`,
    left: "center",
    textStyle: {
      fontSize: 12
    }
  };
  // const animation = false;
  const grid = {
    top: 50,
    bottom: -2,
    left: 12,
    right: 16,
    containLabel: true
  };
  const tooltip = {
    trigger: "axis"
    // axisPointer: {
    //   type: "cross"
    // }
  };
  const xAxis = {
    type: "category",
    splitLine: {
      // show: true
    },
    // boundaryGap: false,
    data: xAxisData
  };
  const yAxis = {
    // name: `${data?.name}${data?.unit ? "（" + data?.unit + "）" : ""}`,
    name: `${data?.unit || "--"}`,
    // nameLocation: "start",
    nameTextStyle: {
      align: "left",
      fontSize: 12
    },
    type: "value",
    splitLine: {
      show: true,
      lineStyle: {
        type: "dashed"
      }
    }
  };
  const series: Array<any> = [];
  const ac = getEchartsBarSeries(seriesMetaData, line);
  series.push(...ac);
  cb && cb({ title, grid, tooltip, xAxis, yAxis, series } as EChartsOption);
};

const getEchartsYAxisMax = (cur: any): number => {
  const { list = [], markLineData = [] } = cur;
  const data_max = list?.reduce((pre, cur) => {
    if (cur?.num > pre) {
      pre = cur.num;
    }
    return pre;
  }, 0);
  const markLineData_max = markLineData?.reduce((pre, cur) => {
    if (cur?.yAxis > pre) {
      pre = cur.yAxis;
    }
    return pre;
  }, 0);
  return Math.max(data_max, markLineData_max);
};

export const formatBulkGasPointsData = (points: Array<any>, data: Array<any>, indicator: string = "SUM"): Array<any> => {
  if (!points.length || !data.length) return [];
  const ar = points?.map((item: any) => {
    const { gasName: name = "", lslValue = null, uslValue = null } = item;
    const list = [];
    const unit = "NM³/H";
    // const markLineData = [lslValue, uslValue].filter(item => typeof item === "number");
    const markLineData = getMarkLineData({ lslValue, uslValue });
    return { ...item, unit, name, list, markLineData };
  });
  const arr = data?.reduce((pre, cur) => {
    const index = pre?.findIndex(item => item.point === cur.point);
    if (index > -1) {
      // const { day: name = "", avg_value = "" } = cur;
      // const num = Number(avg_value);

      const { day: name = "" } = cur;
      // const num = Number(last_value);
      const num = cur[`${indicator.toLowerCase()}_value`];

      pre[index].list.push({ ...cur, name, num });
    }
    return pre;
  }, ar);
  return arr?.reduce((pre, cur) => {
    const id = Math.random().toString(36).slice(2, 10);
    const max = getEchartsYAxisMax(cur);
    cur["max"] = max;
    if (!pre.length) {
      const inSideList = [cur];
      pre?.push({ id, inSideList });
    } else {
      if (pre[pre.length - 1].inSideList?.length === 5) {
        const inSideList = [cur];
        pre?.push({ id, inSideList });
      } else {
        pre[pre.length - 1].inSideList?.push(cur);
      }
    }
    return pre;
  }, []);
};

export const getMarkLineData = data => {
  const {
    u3lValue = null,
    uslValue = null,
    uclValue = null,
    uwlValue = null,
    uaclValue = null,
    targetValue = null,
    l3lValue = null,
    lwlValue = null,
    lclValue = null,
    lslValue = null,
    laclValue = null
  } = data;
  let arr = [];
  if (typeof u3lValue === "number") {
    arr?.push({
      name: "U3L值",
      yAxis: u3lValue,
      lineStyle: {
        color: "#3bf65c",
        width: "1",
        type: "solide"
      },
      label: {
        position: "end",
        // formatter: `U3L值${u3lValue}`,
        formatter: u3lValue,
        color: "#3bf65c",
        fontWeight: 600
      }
    });
  }
  if (typeof uslValue === "number") {
    arr?.push({
      name: "USL值",
      yAxis: uslValue,
      lineStyle: {
        color: "#A600FF",
        width: "1",
        type: "solide"
      },
      label: {
        position: "end",
        // formatter: `USL值${uslValue}`,
        formatter: uslValue,
        color: "#A600FF",
        fontWeight: 600
      }
    });
  }
  if (typeof uclValue === "number") {
    arr?.push({
      name: "UCL值",
      yAxis: uclValue,
      lineStyle: {
        color: "#FF0000",
        width: "1",
        type: "dashed"
      },
      label: {
        position: "end",
        // formatter: `UCL值${uclValue}`,
        formatter: uclValue,
        color: "#FF0000",
        fontWeight: 600
      }
    });
  }
  if (typeof uwlValue === "number") {
    arr?.push({
      name: "UWL值",
      yAxis: uwlValue,
      lineStyle: {
        color: "#FF9900",
        width: "1",
        type: "dashed"
      },
      label: {
        position: "end",
        // formatter: `UWL值${uwlValue}`,
        formatter: uwlValue,
        color: "#FF9900",
        fontWeight: 600
      }
    });
  }
  if (typeof uaclValue === "number") {
    arr?.push({
      name: "上自控线",
      yAxis: uaclValue,
      lineStyle: {
        color: "#3B82F6",
        width: "1",
        type: "dashed"
      },
      label: {
        position: "end",
        // formatter: `上自控线${uaclValue}`,
        formatter: uaclValue,
        color: "#3B82F6",
        fontWeight: 600
      }
    });
  }
  if (typeof targetValue === "number") {
    arr?.push({
      name: "Target值",
      yAxis: targetValue,
      lineStyle: {
        color: "#00E272",
        width: "1",
        type: "solide"
      },
      label: {
        position: "end",
        // formatter: `Target值${targetValue}`,
        formatter: targetValue,
        color: "#00E272",
        fontWeight: 600
      }
    });
  }
  if (typeof l3lValue === "number") {
    arr?.push({
      name: "L3L值",
      yAxis: l3lValue,
      lineStyle: {
        color: "#3bf65c",
        width: "1",
        type: "solide"
      },
      label: {
        position: "end",
        // formatter: `L3L值${l3lValue}`,
        formatter: l3lValue,
        color: "#3bf65c",
        fontWeight: 600
      }
    });
  }
  if (typeof lwlValue === "number") {
    arr?.push({
      name: "LWL值",
      yAxis: lwlValue,
      lineStyle: {
        color: "#FF9900",
        width: "1",
        type: "dashed"
      },
      label: {
        position: "end",
        // formatter: `LWL值${lwlValue}`,
        formatter: lwlValue,
        color: "#FF9900",
        fontWeight: 600
      }
    });
  }
  if (typeof lclValue === "number") {
    arr?.push({
      name: "LCL值",
      yAxis: lclValue,
      lineStyle: {
        color: "#FF0000",
        width: "1",
        type: "dashed"
      },
      label: {
        position: "end",
        // formatter: `LCL值${lclValue}`,
        formatter: lclValue,
        color: "#FF0000",
        fontWeight: 600
      }
    });
  }
  if (typeof lslValue === "number") {
    arr?.push({
      name: "LSL值",
      yAxis: lslValue,
      lineStyle: {
        color: "#A600FF",
        width: "1",
        type: "solide"
      },
      label: {
        position: "end",
        // formatter: `LSL值${lslValue}`,
        formatter: lslValue,
        color: "#A600FF",
        fontWeight: 600
      }
    });
  }
  if (typeof laclValue === "number") {
    arr?.push({
      name: "下自控线",
      yAxis: laclValue,
      lineStyle: {
        color: "#3B82F6",
        width: "1",
        type: "dashed"
      },
      label: {
        position: "end",
        // formatter: `下自控线${laclValue}`,
        formatter: laclValue,
        color: "#3B82F6",
        fontWeight: 600
      }
    });
  }
  return arr;
};

export const formatSPCPointsData = (data: Array<any>, needMarkLine?: boolean): Array<any> => {
  return data?.reduce((pre, cur) => {
    const { indicatorName: name = "", formatPointValues: list = [], pointUnit: unit = "" } = cur;
    cur = { ...cur, name, list, unit };
    if (needMarkLine) {
      cur["markLineData"] = getMarkLineData(cur);
    }
    const id = Math.random().toString(36).slice(2, 10);
    const max = getEchartsYAxisMax(cur);
    cur["max"] = max;
    if (!pre.length) {
      const inSideList = [cur];
      pre?.push({ id, inSideList });
    } else {
      if (pre[pre.length - 1].inSideList?.length === 3) {
        const inSideList = [cur];
        pre?.push({ id, inSideList });
      } else {
        pre[pre.length - 1].inSideList?.push(cur);
      }
    }
    return pre;
  }, []);
};
